package com.ming.common.dynamic.loader.jar_class_loader;

import com.ming.common.dynamic.loader.class_loader.DynamicClass;
import com.ming.common.dynamic.loader.class_loader.DynamicClassLoader;
import com.ming.common.dynamic.loader.jar_loader.DynamicUtil;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 将外部jar读入内存中
 */
public class DynamicJarClass {
    String[] filePath;
    String javaSourceCode;
    String fullClassName;

    //private URLClassLoader urlClassLoader;
    private DynamicClassLoader myClassLoader;

    public DynamicJarClass(String... filePath) {
        this.filePath = filePath;
    }

    public static DynamicJarClass init(String... filePath) {
        System.out.println("初始化jar filePath:" + filePath);
        return new DynamicJarClass(filePath);
    }

    public DynamicJarClass javaSourceCode(String javaSourceCode) {
        this.javaSourceCode = javaSourceCode;
        return this;
    }

    public DynamicJarClass fullClassName(String fullClassName) {
        this.fullClassName = fullClassName;
        return this;
    }

    /*public Class<?> load(String fullClassName) {
        try {
            URL url = new File(filePath[0]).toURI().toURL();
            urlClassLoader = new URLClassLoader(new URL[]{url});
            Class<?> aClass = urlClassLoader.loadClass(fullClassName);
            return aClass;
        } catch (MalformedURLException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }*/

    public Class<?> load() {
        Class<?> clasz = null;
        try {
            List<String> list = Arrays.asList(
                    "-classpath", filePath[0]
            );
            DynamicClass dynamicClass = DynamicClass.init(javaSourceCode, fullClassName)
                    .config(list)
                    .compiler();
            clasz = dynamicClass.load();
            myClassLoader = dynamicClass.getMyClassLoader();

            Set<String> importList = DynamicUtil.getImportList(javaSourceCode);
            aa: for (String importInfo : importList){
                for (String path : filePath){

                    //loadAll(importInfo);
                    URL url = new File(path).toURI().toURL();
                    URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url});
                    File jarFile = new File(path);
                    JarFile jar = new JarFile(jarFile);
                    Enumeration<JarEntry> entries = jar.entries();
                    while (entries.hasMoreElements()) {
                        JarEntry entry = entries.nextElement();
                        if (entry.getName().endsWith(".class")) {
                            String className = entry.getName().replace("/", ".").replace(".class", "");
                            // 先检查类是否存在
                            //if(className.contains("$") && className.startsWith(importInfo)){
                            //    System.out.println(className);

                            if(!className.contains("net.sf.cglib.proxy.MethodInterceptor")){
                                urlClassLoader.loadClass(className);
                            }

                            //}
                        }
                    }

                    /*DynamicJar dynamicJar = DynamicJar.init(path);
                    dynamicJar.load(importInfo);
                    boolean flag = myClassLoader.loadClassFromURLClassLoader(dynamicJar.getUrlClassLoader(), importInfo);
                    if(flag){
                        continue aa;
                    }*/
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return clasz;
    }

    public DynamicClassLoader getMyClassLoader() {
        return myClassLoader;
    }


    public void loadAll(String importInfo) {
        try {
            for (String path : filePath){
                File jarFile = new File(path);
                URL url = new File(path).toURI().toURL();
                JarFile jar = new JarFile(jarFile);
                Enumeration<JarEntry> entries = jar.entries();
                while (entries.hasMoreElements()) {
                    JarEntry entry = entries.nextElement();
                    if (entry.getName().endsWith(".class")) {
                        String className = entry.getName().replace("/", ".").replace(".class", "");
                        // 先检查类是否存在
                        if(importInfo.startsWith(className)){
                            System.out.println(className);
                            myClassLoader.loadClass(className);
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

//    public byte[] loadClassFromURLClassLoader(URLClassLoader urlClassLoader, String className) {
//        try {
//            Class<?> loadedClass = urlClassLoader.loadClass(className);
//            InputStream classStream = loadedClass.getResourceAsStream("/" + className.replace('.', '/') + ".class");
//            return readStreamToBytes(classStream);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        return null;
//    }

//    private byte[] readStreamToBytes(InputStream in) throws IOException {
//        ByteArrayOutputStream out = new ByteArrayOutputStream();
//        byte[] buffer = new byte[1024];
//        int bytesRead;
//        while ((bytesRead = in.read(buffer)) != -1) {
//            out.write(buffer, 0, bytesRead);
//        }
//        return out.toByteArray();
//    }

//    public URLClassLoader getUrlClassLoader() {
//        return urlClassLoader;
//    }
}

